import logging
import os

from flask import jsonify, request, send_from_directory
from werkzeug.exceptions import BadRequest, NotFound, InternalServerError

from app import db
from app.model.models import DeepfakeVideo
from app.utils import file_utils
from . import bp

LOG = logging.getLogger(__name__)


@bp.route('/deepfake/video', methods=['POST'])
def upload_video():
    video = request.files.get('video')
    if not video:
        raise BadRequest('Illegal Request!')
    video_name = video.filename
    video_entity = DeepfakeVideo.query.filter_by(video_name=video_name).first()
    if video_entity:
        raise BadRequest('Video already exists!')
    # timestamp = int(round(datetime.now().timestamp()))
    # file_name = "{}_{}{}".format(video_name[:-4], timestamp, video_name[-4:])
    success = file_utils.save_video(video, video_name)
    if success:
        video = DeepfakeVideo()
        video.video_name = video_name
        video.status = 0
        video.progress = 0
        video.probability = 0.
        db.session.add(video)
        db.session.commit()
        return jsonify(success=True, data=video_name, status_code=200)
    else:
        return InternalServerError(description='Video save failed!')


@bp.route('/deepfake/videos', methods=['GET'])
def get_videos():
    page = request.args.get('page', 1, type=int)
    per_page = min(request.args.get('per_page', 10, type=int), 100)
    video_name = request.args.get('videoName', None)
    if video_name:
        query = DeepfakeVideo.query.filter(
            DeepfakeVideo.video_name.like(f'{video_name}%')).order_by(DeepfakeVideo.id.desc())
    else:
        query = DeepfakeVideo.query.order_by(DeepfakeVideo.id.desc())
    data = DeepfakeVideo.to_collection_dict(query, page, per_page, 'api.get_videos')
    return jsonify(success=True, data=data, status_code=200)


@bp.route('/deepfake/video/<path:video_name>', methods=['GET'])
def view_video(video_name):
    if not video_name:
        raise BadRequest('Illegal Request!')
    data_path = os.path.join(file_utils.VIDEO_FOLDER, video_name)
    if not os.path.exists(data_path):
        raise NotFound()
    if video_name.endswith('.mp4'):
        mimetype = 'video/mp4'
    elif video_name.endswith('.webm'):
        mimetype = 'video/webm'
    else:
        mimetype = 'video/mp4'
    return send_from_directory(file_utils.VIDEO_FOLDER, video_name, mimetype=mimetype, as_attachment=False)


@bp.route('/deepfake/video/<path:video_id>', methods=['DELETE'])
def delete_video(video_id):
    if not video_id:
        raise BadRequest('Illegal Request!')
    video_entity = DeepfakeVideo.query.filter_by(id=video_id).first()
    if not video_entity:
        raise BadRequest('Illegal argument!')

    file_utils.remove_video(video_entity.video_name)
    file_utils.remove_video(f'{video_entity.video_name[:-4]}_mask.webm')
    db.session.delete(video_entity)
    db.session.commit()
    return jsonify(success=True, data=None, status_code=200)
